#include "texture_manager.h"
#include "camera.h"

using namespace alice;

TextureManager* TextureManager::instance_ = nullptr;

bool TextureManager::Load(std::string id, std::string filename) {
  SDL_Surface* surface = IMG_Load(filename.c_str());
  if (surface == nullptr) {
    SDL_Log("Failed to load texture: %s %s\n", id.c_str(), SDL_GetError());
    return false;
  }

  SDL_Texture* texture = SDL_CreateTextureFromSurface(Director::GetInstance()->GetRenderer(), surface);
  if (texture == nullptr) {
    SDL_Log("Failed to load texture from surface: %s %s\n", id.c_str(), SDL_GetError());
    return false;
  }

  texture_map_[id] = texture;

  return true;
}

void TextureManager::Draw(std::string id, int x, int y, int w, int h, SDL_RendererFlip flip) {
  SDL_Rect srcRect = {0, 0, w, h};
 
  Vector2D camera_position = Camera::GetInstance()->GetPosition();
  int cx = camera_position.X;
  int cy = camera_position.Y;

  SDL_Rect dstRect = {x - cx, y - cy, w, h};
  SDL_RenderCopyEx(Director::GetInstance()->GetRenderer(), texture_map_[id], &srcRect, &dstRect, 0, nullptr, flip);
}

void TextureManager::DrawFrame(std::string id, int x, int y, int w, int h, int row, int frame, SDL_RendererFlip flip) {
  SDL_Rect srcRect = {w*frame, h*(row-1), w, h};

  Vector2D camera_position = Camera::GetInstance()->GetPosition();
  int cx = camera_position.X;
  int cy = camera_position.Y;

  SDL_Rect dstRect = {x - cx, y -cy, w, h};
  SDL_RenderCopyEx(Director::GetInstance()->GetRenderer(), texture_map_[id], &srcRect, &dstRect, 0, nullptr, flip);
}

void TextureManager::DrawTile(std::string tile_id, int x, int y, int tile_size, int row, int column, SDL_RendererFlip flip) {
  SDL_Rect srcRect = {tile_size*column, tile_size*row, tile_size, tile_size};
  
  Vector2D camera_position = Camera::GetInstance()->GetPosition();
  int cx = camera_position.X;
  int cy = camera_position.Y;

  SDL_Rect dstRect = {x - cx, y - cy, tile_size, tile_size};
  SDL_RenderCopyEx(Director::GetInstance()->GetRenderer(), texture_map_[tile_id], &srcRect, &dstRect, 0, 0, flip);
}

void TextureManager::Drop(std::string id) {
  SDL_DestroyTexture(texture_map_[id]);
  texture_map_.erase(id);
}

void TextureManager::Clean() {
  std::map<std::string, SDL_Texture*>::iterator it;
  for (it = texture_map_.begin(); it != texture_map_.end(); it++) {
    SDL_DestroyTexture(it->second);
  }
  texture_map_.clear();
  SDL_Log("Texture dict cleaned\n");
}
